
local _ROOT = (...):match("(.-)[^%.]+$")

local utils = require("utils")
local repl = require("love-repl") 

local path = require( _ROOT .. ".pathfinding")
local console = require("console")
local draw = require("draw")

local items = require("items")
local mobs  = require("mobs")
local tiles = require("tiles")
local callbacks = require("callbacks")
local headings = require("headings")

local control = require("control")


-- This function initialises static global variables
-- and spritesheets
function initGlobals()

	love.graphics.setCaption("ColdRL")

	math.randomseed( os.time() )

	-- Init debug console
	 repl.initialize()

	 -- General variables --------------------------------------------------------------------------------------------------------------

	letterMap  = {"a","b","c","d","e","f","g","h","i","j"}

	weaponDanger = {"none", "weak", "average", "strong", "deadly"}

	weaponColor = {}
	weaponColor[1] = {155,155,155,255} -- grey
	weaponColor[2] = {0,0,255,255}  -- blue
	weaponColor[3] = {0,255,0,255} -- green
	weaponColor[4] = {255,255,0,255} --yellow
	weaponColor[5] = {255,0,0,255} -- red

	weaponDamage = {0,35,50,80,100}

	-- Player's damage ratio
	playerDamageFactor = 0.75

	-- armour scale
	armourString = {"unarmoured", "lightly armoured", "heavily armoured", "a fortress of armour"}
	armourPower  = {1.0,0.6,0.5,0.30}

	-- Enemy level drop rate
	dropRate = {40,40,45,45,50}

	-- damage messages
	damageFactor = {20, 40, 60, 80, 100}
	damageString = {
					"light",
					"moderate",
					"severe",
					"crippling",
					"lethal"
					}

	-- World data ------------------------------------------------------------------------------------------------------------------------
	worldData = {}
	worldData["size"] = {}
	worldData.size["x"] = 15
	worldData.size["y"] = 15


	-- Tiles and quads ------------------------------------------------------------------------------------------------------------------------
	snowTileMap = love.graphics.newImage( "tiles.png" )
	tileSize = 32

	terrainTiles = {}
	terrainTiles[1] = love.graphics.newQuad(1*tileSize,1*tileSize,tileSize,tileSize,320,96)
	terrainTiles[2] = love.graphics.newQuad(0,1*tileSize,tileSize,tileSize,320,96)
	terrainTiles[3] = love.graphics.newQuad(3*tileSize,1*tileSize,tileSize,tileSize,320,96)
	terrainTiles[4] = love.graphics.newQuad(4*tileSize,1*tileSize,tileSize,tileSize,320,96)

	objectSprites = {}
	objectSprites["TreeBase"] = love.graphics.newQuad(6*tileSize,1*tileSize,tileSize,tileSize,320,96)
	objectSprites["TreeTop"] = love.graphics.newQuad(5*tileSize,1*tileSize,tileSize,tileSize,320,96)
	--objectSprites["TreeBase"] = love.graphics.newQuad(8*tileSize,1*tileSize,tileSize,tileSize,320,96)
	--objectSprites["TreeTop"] = love.graphics.newQuad(7*tileSize,1*tileSize,tileSize,tileSize,320,96)

	-- alert exclamation mark
	alertQuad = love.graphics.newQuad(8*tileSize,2*tileSize,tileSize,tileSize,320,96)

	-- character sprite
	characterQuad  = love.graphics.newQuad(9*tileSize,2*tileSize,32,32,320,96)

	-- target crosshair sprite
	crossHairQuad = love.graphics.newQuad(0,0,32,32,320,96)

	-- dropped item quad
	itemQuad = love.graphics.newQuad(2*tileSize,1*tileSize,tileSize,tileSize,320,96)

	-- mob tiles ------------------------------------------------------------------------------------------
	mobSprites = {}
	mobSprites["my"] = {}
	mobSprites["my"].alive = love.graphics.newQuad(1*tileSize,0*tileSize,tileSize,tileSize,320,96)
	mobSprites["my"].dead  = love.graphics.newQuad(2*tileSize,0*tileSize,tileSize,tileSize,320,96)

	mobSprites["rob"] = {}
	mobSprites["rob"].alive = love.graphics.newQuad(3*tileSize,0,tileSize,tileSize,320,96)
	mobSprites["rob"].dead  = love.graphics.newQuad(4*tileSize,0,tileSize,tileSize,320,96)

	mobSprites["jug"] = {}
	mobSprites["jug"].alive = love.graphics.newQuad(5*tileSize,0*tileSize,tileSize,tileSize,320,96)
	mobSprites["jug"].dead  = love.graphics.newQuad(6*tileSize,0*tileSize,tileSize,tileSize,320,96)


	-- Tree blocking information -------
	isBlocking = {}
	isBlocking["TreeBase"] = true
	isBlocking["TreeTop"] = false

	-- initialise item DB
	initItems()


end


-- initialise game (instance) specific variables
function initGame()

-- Init player console
	 initConsole()

-- Display start screen
	controlMode = "movementmode"

-- Targetting information and callbacks
	usingItem = nil
	targetCallback = nil
	targetLoc = {7,7}


-- Player Character information --------------------------------------------
	characterLoc   = {8,8}
	characterHeat  = 100
	characterArmour = 1
	characterHealth = 100
	characterTargetLoc = {characterLoc[1],characterLoc[2]}

	distanceTarget = 600
	distanceFromCenter = {0,0}

	characterKills = 0
	characterTurns = 0

-- Heading circular linked list
	playerHeading = genHeading()

-- Player inventory
	playerItems = {}
	for  i = 1, 9, 1 do
		playerItems[i] = deepcopy(gameItems.empty[1])
	end

-- start inventory
	initInventory()


-- World generation -------------------------------------------------------

-- alive mobiles vector
	activeMobs = nil

-- Tile Table
	localTerrain = {}
	for i = 1, worldData.size.x, 1 do
		localTerrain[i] = {}
		for j = 1,worldData.size.y,1 do
			localTerrain[i][j] = {}
			genTile(i,j,localTerrain[i][j])
		end
	end

	-- Kill generated mobs
	local mobList = activeMobs
    while mobList do
    	mobList.value.alive = false
    	mobList = mobList.next
    end


-- Final preparations -----------------------------------------------------

	-- Check field of vision
	CheckFOV(false)

	-- Initialise jumper
	initPathfinding(localTerrain)

end


-- Main game Loop --------------------------------------------------------------

function gameTick()

	-- health check
	if (characterHealth <= 0) then killPlayer("bled to death") return end

	-- update items
	itemTick()

	--	Drop heat
	characterHeat = characterHeat - 1

	if (characterHeat <= 0) then
		characterHeat = 0
		characterHealth = characterHealth - 10

		if characterHealth <= 0 then
			killPlayer("succumbed to the cold")
		else
			addConsoleMessage("You struggle to remain conscious, the cold is killing you!", "red")
		end
	end



	updatePathfinding(localTerrain)

-- update mob AI
	AIList = activeMobs
	while AIList do
		if (AIList.value.alive == true ) then
			mobAI(AIList.value)
			updatePathfinding(localTerrain) -- update mid way
		end

		AIList = AIList.next
	end

	if (characterHealth > 0) then CheckFOV(false)
		else CheckFOV(true) end

	characterTurns = characterTurns + 1

	if (characterHealth <= 0 ) then controlMode = "deadmode" end

end


--- LOVE Functions  -------------------------------------------------------------------------

function love.load()
	
	initGlobals()
	initGame()

end


function love.keypressed(key, unicode)

	-- DEBUG CONSOLE ---------------------------------------------------
	if key == 'tab' then
    	repl.toggle()
    	return
  	end

	-- repl console
	if repl.toggled() then
    	repl.keypressed(key, unicode)
    	return
  	end

  	-- Command handling ------------------------------------------------------
	if (controlMode == "movementmode") then handleMoveControl(key,unicode)
	elseif (controlMode == "targetmode") then handleTargetControl(key,unicode)
	elseif (controlMode == "pickup") then handlePickupControl(key,unicode)
	elseif (controlMode == "dropmode") then handleDropControl(key,unicode)
	elseif (controlMode == "consolemode") then handleConsoleControl(key,unicode)
	elseif (controlMode == "deadmode") then handleDeadControl(key,unicode) end

	-- General keys
   if (key == 'q' and love.keyboard.isDown("lshift")==true ) then
		love.event.quit( )
	end

	if (characterHealth > 0) then CheckFOV(false)
		else CheckFOV(true) end
end



--- not used atm
function love.mousepressed(x, y, button)
  if repl.toggled() then
    repl.mousepressed(x, y, button)
    return
  end
end

function love.update()

	if (characterHealth <= 0 ) then controlMode = "deadmode" end


  -- If the REPL is open, you probably don't want to update your game
  if repl.toggled() then
    return
  end
end
